using MediatR;
using S.O.Api.Write.Application.Command.Medical;
using S.O.Domain.Medical;
using S.O.ErrorCode;
using S.O.Interstructrue;
using S.O.Interstructrue.Base;

namespace S.O.Api.Write.Application.Handler.Medical
{
    /// <summary>
    /// 取消挂号记录处理器
    /// 支持患者取消已预约的挂号，释放医生时间资源
    /// </summary>
    public class CancelRegistrationHandler : IRequestHandler<CancelRegistrationCommand, APIResult<bool>>
    {
        /// <summary>
        /// 数据库上下文
        /// </summary>
        private readonly RBACDbContext _context;
        
        /// <summary>
        /// 挂号记录仓储
        /// </summary>
        private readonly IBaseRepository<RegistrationModel> _registrationRepository;

        /// <summary>
        /// 构造函数，通过依赖注入初始化所需服务
        /// </summary>
        /// <param name="context">数据库上下文</param>
        /// <param name="registrationRepository">挂号记录仓储</param>
        public CancelRegistrationHandler(
            RBACDbContext context,
            IBaseRepository<RegistrationModel> registrationRepository)
        {
            _context = context;
            _registrationRepository = registrationRepository;
        }

        /// <summary>
        /// 处理取消挂号记录命令
        /// </summary>
        /// <param name="request">取消挂号记录命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>取消结果</returns>
        public async Task<APIResult<bool>> Handle(CancelRegistrationCommand request, CancellationToken cancellationToken)
        {
            try
            {
                // 查找挂号记录
                var registration = _registrationRepository.GetModel(request.Id);
                if (registration == null || !registration.IsEnable)
                {
                    return new APIResult<bool> { Code = APIEnums.Error, Msg = "挂号记录不存在" };
                }
                
                // 检查挂号状态
                if (registration.Status == "已取消")
                {
                    return new APIResult<bool> { Code = APIEnums.Error, Msg = "该挂号记录已经取消" };
                }
                
                if (registration.Status == "已完成")
                {
                    return new APIResult<bool> { Code = APIEnums.Error, Msg = "该挂号记录已完成，无法取消" };
                }
                
                if (registration.Status == "就诊中")
                {
                    return new APIResult<bool> { Code = APIEnums.Error, Msg = "患者正在就诊中，无法取消挂号" };
                }
                
                // 检查取消时间限制（就诊当天不能取消）
                if (registration.VisitDate.Date == DateTime.Now.Date)
                {
                    return new APIResult<bool> { Code = APIEnums.Error, Msg = "就诊当天不能取消挂号，如有特殊情况请联系医院" };
                }
                
                // 更新挂号状态为已取消
                registration.Status = "已取消";
                // 更新时间处理（如果需要可以添加UpdateTime字段到BaseEntity）
                
                // 如果需要退费，这里可以添加退费逻辑
                if (request.IsRefund)
                {
                    // TODO: 实现退费逻辑
                    // 可以调用支付系统的退费接口
                }
                
                // 保存更改
                _registrationRepository.Update(registration);
                _context.SaveChanges();
                
                var message = request.IsRefund ? "挂号已取消，退费将在3-5个工作日内到账" : "挂号已取消";
                return new APIResult<bool> { Code = APIEnums.Success, Data = true, Msg = message };
            }
            catch (Exception ex)
            {
                return new APIResult<bool> { Code = APIEnums.Error, Msg = $"取消挂号失败：{ex.Message}" };
            }
        }
    }
}